package com.plant.classify.service.impl;

import com.plant.classify.domain.Classif;
import com.plant.classify.mapper.ClassifyMapper;
import com.plant.classify.service.ClassifyService;
import com.plant.classify.util.CartServiceUtil;
import com.plant.classify.vo.AddressVo;
import com.plant.classify.vo.OrderInsert;
import com.plant.classify.vo.OrderVo;
import com.plant.classify.vo.productVo;
import com.plant.common.utils.IdWorker;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.TimeUnit;

/**
 * @author: 华景壘
 * @date: 2024/8/21 19:59
 * @description:
 */
@Service
@Slf4j
public class ClassifyServiceImpl implements ClassifyService {
    @Autowired
    private ClassifyMapper classifyMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private CartServiceUtil cartServiceUtil;


    @Override
    public List<Classif> getClassify() {
        List<Classif> list;
        try {
            // 获取 redis 存的热点分类
            list = redisTemplate.opsForList().range("classify", 0, -1);
            if (Optional.ofNullable(list).map(List::size).orElse(0) > 0) {
                return list;
            } else {
                list = classifyMapper.getClassify();
                // 使用 ListOperations 存储数据到 Redis
                ListOperations<String, Classif> listOperations = redisTemplate.opsForList();
                for (Classif classif : list) {
                    try {
                        listOperations.rightPush("classify", classif);
                    } catch (Exception e) {
                        throw new RuntimeException("存储数据到 Redis 失败", e);
                    }
                }
                // 设置过期时间为二小时
                try {
                    redisTemplate.expire("classify", 2, TimeUnit.HOURS);
                } catch (Exception e) {
                    throw new RuntimeException("设置 Redis 过期时间失败", e);
                }
                return list;
            }
        } catch (Exception e) {
            throw new RuntimeException("获取分类数据过程中出现错误", e);
        }
    }

    /**
     * 查询商品
     * @param id
     * @return
     */
    @Override
    public List<productVo> findByGoods(Integer id) {
        return classifyMapper.findByGoods(id);
    }


    /**
     * 将商品添加到购物车
     * 如果购物车中已存在相同商品，则增加该商品的数量；如果商品不存在，则将该商品添加到购物车中
     * @param orderVo 商品信息封装对象，包含商品ID、价格和数量等信息
     */
    public void setCart(OrderVo orderVo) {
        IdWorker idWorker = new IdWorker();
        try {
            // 从 Redis 中获取购物车中的所有商品
            List<OrderVo> list = redisTemplate.opsForList().range("toCart"+orderVo.getUid(), 0, -1);
            if (list != null && !list.isEmpty()) {
                // 查找购物车中是否存在相同商品的索引
                int duplicateIndex = cartServiceUtil.findDuplicateIndex(list, orderVo);
                if (duplicateIndex != -1) {
                    OrderVo duplicateOrder = list.get(duplicateIndex);
                    duplicateOrder.setNum(duplicateOrder.getNum() + 1);
                    // 更新购物车中的商品数量
                    try {
                        redisTemplate.opsForList().set("toCart"+orderVo.getUid(), duplicateIndex, duplicateOrder);
                    } catch (Exception e) {
                        throw new RuntimeException("更新购物车商品数量失败", e);
                    }
                } else {
                    cartServiceUtil.addNewOrder(orderVo, idWorker);
                }
            } else {
                cartServiceUtil.addNewOrder(orderVo, idWorker);
            }
        } catch (Exception e) {
            throw new RuntimeException("获取购物车列表失败", e);
        }
    }


    /**
     * 根据用户 ID 查找购物车中的商品列表.
     *
     * @param uid 用户 ID
     * @return 符合条件的购物车商品列表
     */
    public List<OrderVo> findAllToCart(Integer uid) {
        try {
            List<OrderVo> allOrders = redisTemplate.opsForList().range("toCart"+uid, 0, -1);
            List<OrderVo> resultList = new ArrayList<>();
            if (allOrders != null && !allOrders.isEmpty()) {
                for (OrderVo orderVo : allOrders) {
                    if (Objects.equals(orderVo.getUid(), uid)) {
                        resultList.add(orderVo);
                    }
                }
            }
            return resultList;
        } catch (Exception e) {
            // 记录日志或者抛出自定义异常
            throw new RuntimeException("获取购物车列表失败", e);
        }
    }

    /**
     * 订单提交保存数据库
     * @param orderInsert
     * @return
     */
    @Transactional
    @Override
    public Integer orderDetail(OrderInsert orderInsert) {
        log.info("添加订单{}", orderInsert);
        //判断订单是否重复提交
        Object oid = redisTemplate.opsForValue().get("oid"+orderInsert.getUid());
        if (oid == null) {
            cartServiceUtil.OrderSave(orderInsert);
        } else {
            if (oid.equals(orderInsert.getOrderId())) {
                return 1;//1 代表订单重复
            } else {
                cartServiceUtil.OrderSave(orderInsert);
            }
        }
        return 2;  //2 代表订单提交成功 不重复
    }


    /**
     * 更新订单状态
     * @param orderId
     */
    @Override
    public void UpdateStatus(String orderId) {
        classifyMapper.UpdateStatus(orderId);
    }

    /**
     * 查询用户地址
     * @param userId
     * @return
     */
    @Override
    public AddressVo UserAddress(Integer userId) {
        return classifyMapper.UserAddress(userId);
    }


    /**
     * B端分类添加
     * @param classif
     */
    @Override
    public void save(Classif classif) {
        classifyMapper.save(classif);
    }

    /**
     * 根据id查询分类
     * @param id
     * @return
     */
    @Override
    public Classif getClassifyId(Integer id) {
        return classifyMapper.getClassifyId(id);
    }

    /**
     * B端分类修改
     * @param classif
     */

    @Override
    public void updateClassify(Classif classif) {
        classifyMapper.updateClassify(classif);
    }

    /**
     * 根据id查询商品详情
     * @param id
     * @return
     */
    @Override
    public productVo findByDetail(Integer id) {
        return classifyMapper.findByDetail(id);
    }
}
